package snake;

import java.util.LinkedList;
import java.io.*;

class Grid {

    public final boolean status[][];
    private final int width;
    private final int height;
    private int score = 0;
    private int record;

    private Snake snake;
    private Node food;

    //蛇的初始方向默认向左；
    private Direction snakeDirection = Direction.LEFT;

    Grid(int width, int height) throws Exception {
        this.height = height;
        this.width = width;
        status = new boolean[width][height];//蛇占据的地方为true

        initSnake();
        createFood();
        this.record = getRecord();

    }

    private int getRecord() throws Exception {
        BufferedReader recordFile = new BufferedReader(new FileReader("C:\\Users\\SixStart\\IdeaProjects\\简单小项目\\src\\snake\\scoresRecord.txt"));
        String a = recordFile.readLine();
        this.record = Integer.parseInt(a.trim());
        recordFile.close();
        return record;
    }

    public int getScore(){
        return score;
    }

    public int returnRecord(){
        return record;
    }

    public int increaseScore(){
        score++;
        return score;
    }

    public void changeRecord(int result) throws Exception{
        FileWriter fw = new FileWriter("C:\\Users\\SixStart\\IdeaProjects\\简单小项目\\src\\snake\\scoresRecord.txt",false);
        BufferedWriter recordFile = new BufferedWriter(fw);
        recordFile.write(String.valueOf(result));
        fw.flush();
        recordFile.close();
    }

    private Node snakeAddBody(Node body){
        status[body.getX()][body.getY()] = true;
        snake.addBody(body);
        return body;
    }

    private Snake initSnake(){
        this.snake = new Snake();
        //蛇初始为横着的状态，长度为width的三分之一
        int headX = (int)(width/6*Math.random()+width/3);
        int headY = (int)(height*Math.random());
        while(headY <= 0|| headY>height-2){
            headY = (int)(height*Math.random());
        }
        Node head = new Node(headX,headY);
        snakeAddBody(head);
        for (int i=1; i<(int)(width/3); i++){
            headX++;
            snakeAddBody(new Node(headX,headY));
        }
        return snake;
    }

    private Node createFood(){
        int foodX = (int)(width*Math.random());
        int foodY = (int)(height*Math.random());
        while(status[foodX][foodY] || foodX<=0 || foodX>width-2 || foodY <= 0 || foodY>height-2){
            foodX = (int)(width*Math.random());
            foodY = (int)(height*Math.random());
        }
        this.food = new Node(foodX,foodY);
        return food;
    }

    private Node snakeMove(){
        Node tail = snake.move(snakeDirection);
        status[snake.getHead().getX()][snake.getHead().getY()] = true;
        status[tail.getX()][tail.getY()] = false;
        return tail;
    }


    public boolean nextRound(){
        //移动后游戏继续返回true，否则返回false
        Node tail = snakeMove();
        if(isHeadValid()){
            if (isHeadFood()) {
                snake.addBody(tail);
                status[tail.getX()][tail.getY()] = true;
                createFood();
                increaseScore();
            }
            return true;
        }
        else{
            return false;
        }
    }

    private boolean isHeadValid(){
        Node head = snake.getHead();
        int headX = head.getX();
        int headY = head.getY();
        if (headX <= 0 || headX >= width-1 || headY <= 0 || headY >= height-1 || headTouchBody(headX,headY)){
            return false;
        }
        else{
            return true;
        }
    }

    private boolean headTouchBody(int headX, int headY){
        LinkedList<Node> a = snake.getBody();
        for (int i=1; i<a.size(); i++){
            if (headX == a.get(i).getX() && headY == a.get(i).getY()){
                return true;
            }
        }
        return false;
    }

    private boolean isHeadFood(){
        Node head = snake.getHead();
        if (head.getX() == food.getX() && head.getY() == food.getY()){
            return true;
        }
        else{
            return false;
        }
    }

    public void changeDirection(Direction newDirection){
        if (snakeDirection.compatibleWith(newDirection)){
            snakeDirection = newDirection;
        }
    }

    public Snake getSnake(){
        return this.snake;
    }

    public Node getFood(){
        return this.food;
    }
}
